package com.zmc.member.infrastructure.component.shopping.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.zmc.common.constant.CacheConstants;
import com.zmc.common.domain.es.EsSkuAttr;
import com.zmc.common.domain.es.EsSkuEntity;
import com.zmc.common.domain.query.goods.GoodSkuFeignQuery;
import com.zmc.common.utils.JsonUtils;
import com.zmc.common.utils.PageUtils;
import com.zmc.common.utils.redis.RedisCache;
import com.zmc.common.utils.token.AuthTokenService;
import com.zmc.common.vo.PageVo;
import com.zmc.member.feign.SearchFeignService;
import com.zmc.member.infrastructure.bean.query.ShoppingCartQuery;
import com.zmc.member.infrastructure.bean.vo.*;
import com.zmc.member.infrastructure.component.shopping.ShoppingCartStrategyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author：zmc
 * @Date：2025/5/27 14:07
 */
@Component
public class ShoppingCartCacheServiceImpl implements ShoppingCartStrategyService {

    @Autowired
    private AuthTokenService authTokenService;

    @Autowired
    private SearchFeignService searchFeignService;

    @Autowired
    private RedisCache redisCache;

    public static String upLoadPrefix = "http://localhost:8080/api";

    @Override
    public void merge(List<ShoppingCartVo> list) {
        for (ShoppingCartVo shoppingCartVo : list) {
            redisCache.setCacheMapValue(getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId()), shoppingCartVo.getSkuId(), JSON.toJSONString(shoppingCartVo));
        }
    }

    @Override
    public void delete(List<String> skuIds) {
        redisCache.deleteCacheMapValue(getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId()), skuIds);
    }

    @Override
    public void add(ShoppingCartVo shoppingCartVo) {
        String shoppingCartCacheKey = getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId());
        String skuId = shoppingCartVo.getSkuId();
        Object value = redisCache.getCacheMapValue(shoppingCartCacheKey, skuId);
        if (Objects.isNull(value)) {
            redisCache.setCacheMapValue(shoppingCartCacheKey, skuId, JSON.toJSONString(shoppingCartVo));
            return;
        }
        ShoppingCartVo entity = JSON.to(ShoppingCartVo.class, value);
        entity.setCount(entity.getCount() + shoppingCartVo.getCount());
        redisCache.setCacheMapValue(shoppingCartCacheKey, skuId, JSON.toJSONString(entity));
    }

    @Override
    public void updateShoppingCartItemBySkuId(ShoppingCartItemUpdateCountVo vo) {
        String cacheKey = getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId());
        ShoppingCartVo shoppingCartVo = JSON.to(ShoppingCartVo.class, redisCache.getCacheMap(cacheKey).get(vo.getSkuId()));
        shoppingCartVo.setCount(vo.getCount());
        redisCache.setCacheMapValue(cacheKey, vo.getSkuId(), JSON.toJSONString(shoppingCartVo));
    }

    @Override
    public void setSelectedStatus(ShoppingCartSelectedVo vo) {
        String cacheKey = getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId());
        List<String> skuIds = vo.getSkuIds();
        for (String skuId : skuIds) {
            ShoppingCartVo shoppingCartVo = JSON.to(ShoppingCartVo.class, redisCache.getCacheMap(cacheKey).get(skuId));
            shoppingCartVo.setSelected(vo.getSelected());
            redisCache.setCacheMapValue(cacheKey, skuId, JSON.toJSONString(shoppingCartVo));
        }
    }

    @Override
    public void clearHasSelected() {
        String cacheKey = getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId());
        Map<String, Object> cacheMap = redisCache.getCacheMap(cacheKey);
        cacheMap.forEach((sku, obj) -> {
            ShoppingCartVo entity = JSON.to(ShoppingCartVo.class, obj);
            if (Boolean.parseBoolean(entity.getSelected())) {
                redisCache.deleteCacheMapValue(cacheKey, sku);
            }
        });
    }

    @Override
    public List<ShoppingCartVo> getSelectedList(List<String> skuIds) {
        List<ShoppingCartVo> list = new ArrayList<>();
        List<String> cacheList = redisCache.getCacheMapMulti(getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId()), skuIds);
        if (CollectionUtils.isEmpty(cacheList)) {
            return list;
        }
        //从缓存中查询被选中sku列表信息
        cacheList.forEach(value -> {
            list.add(JSONObject.parseObject(value, ShoppingCartVo.class));
        });
        return list.stream().filter(item -> "true".equals(item.getSelected())).collect(Collectors.toList());
    }

    @Override
    public PageUtils shoppingCartList(ShoppingCartQuery cartQuery) {
        Map<String, Object> cacheMap = redisCache.getCacheMap(getShoppingCacheKey(authTokenService.getMemberInfo().getMemberId()));
        if (CollectionUtils.isEmpty(cacheMap)) {
            return new PageUtils(new ArrayList<>(), 0L, (long)cartQuery.getPageSize(), (long) cartQuery.getPageNum());
        }
        List<String> skuIds = new ArrayList<>(cacheMap.keySet());
        GoodSkuFeignQuery query = new GoodSkuFeignQuery();
        query.setSkuIds(skuIds);
        List<EsSkuEntity> esSkuList = JsonUtils.transToArrayClass(searchFeignService.getSkuInfosBySkuIds(query), EsSkuEntity.class);
        List<ShoppingCartItemVo> list = new ArrayList<>();
        cacheMap.forEach((skuId, shoppingCartCacheValue) -> {
            ShoppingCartVo entity = JSON.to(ShoppingCartVo.class, shoppingCartCacheValue);
            EsSkuEntity esSkuEntity = esSkuList.stream().filter(productSkuVo -> Objects.equals(Long.parseLong(skuId), productSkuVo.getSkuId())).findFirst().orElseThrow(RuntimeException::new);
            ShoppingCartItemVo vo = new ShoppingCartItemVo();
            vo.setSpuId(esSkuEntity.getSpuId());
            vo.setName(esSkuEntity.getSpuTitle());
            vo.setSalePrice(esSkuEntity.getSkuPrice());
            //todo
            vo.setPicture(upLoadPrefix + esSkuEntity.getSkuImg());
            vo.setSelected(Boolean.parseBoolean(entity.getSelected()));
            vo.setCount(entity.getCount());
            vo.setSkuId(entity.getSkuId());
            vo.setAttrsText(esSkuEntity.getAttrs().stream().map(EsSkuAttr::getPropertyValue).collect(Collectors.joining(" ")));
            list.add(vo);
        });
        return new PageUtils(list, (long)list.size(),  (long)cartQuery.getPageSize(), (long) cartQuery.getPageNum());
    }

    private String getShoppingCacheKey(String memberId) {
        return CacheConstants.SHOPPING_CART_KEY + memberId;
    }
}
